package org.richin.io.Stream.util;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public final class FastBufferedOutputStream extends FilterOutputStream {

    private byte buf[];
    private int count;

    public FastBufferedOutputStream(OutputStream out) {
        this(out, 8192);
    }

    public FastBufferedOutputStream(OutputStream out, int size) {
        super(out);
        if(size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

    @Override
    public void write(int b) throws IOException {
        if(count >= buf.length) {
            flushBuffer();
        }
        buf[count++] = (byte) b;
    }

    @Override
    public void write(byte b[], int off, int len) throws IOException {
        if(len >= buf.length) {
            flushBuffer();
            out.write(b, off, len);
            return;
        }
        if(len > buf.length - count) {
            flushBuffer();
        }
        System.arraycopy(b, off, buf, count, len);
        count += len;
    }

    @Override
    public synchronized void flush() throws IOException {
        flushBuffer();
        out.flush();
    }

    private void flushBuffer() throws IOException {
        if(count > 0) {
            out.write(buf, 0, count);
            count = 0;
        }
    }
}
